package divtastic.js;

import divtastic.js.Browser;
import divtastic.js.DisplayDiv;


// Adds browser specific tweenable properties to a basic DisplayDiv
// Not full cross browser tested yet may not work in IE
class Divtastic extends DisplayDiv
{
    
    // properties are stored on DisplayDiv.
    //TODO 
    
    public function new(?img: String )
    {
        
        if( img != 'canvas' )
        {
            
            super( img );
            
        }
        else
        {
            // TODO: Check if this works!! probably not?? 
            super();
            _dom.className = 'canvas';
            
        }
        
    }
    
    
    public var scale( get_scale, set_scale ): Float;
    
    private function get_scale( ):Float
    {
        
        if( _scale == null )
        {
            
            _scale = 1;
            _scaleX = 1;
            _scaleY = 1;
        }
        return _scale;
        
    }
    
    private function set_scale( scale_: Float ): Float
    {
        
        var scaleStr    =  Std.string( scale_ );
        var str         = "scale("+ scaleStr + ', ' + scaleStr + ")";
        
        switch( Browser.browserType )
        {
            case WebKit:    untyped _style.WebkitTransform  = str;
            case Opera:     untyped _style.OTransform       = str;
            case Mozilla:   untyped _style.MozTransform     = str;
            case IE:        affineTrans( scale_, 0, 0, scale_, 0, 0 ) ;
        }
        
        _scale  = scale_;
        _scaleX = scale_;
        _scaleY = scale_;
        
        return _scale;
        
    }
    
    

    public var scaleY( get_scaleY, set_scaleY ): Float;
    
    private function get_scaleY( ):Float
    {
        
        if( _scaleY == null ) _scaleY = 1;
        return _scaleY;
        
    }
    
    private function set_scaleY( scaleY_: Float ): Float
    {
        
        switch( Browser.browserType )
        {
            case WebKit:    untyped _style.WebkitTransform  = "scaleY("+ Std.string( scaleY_ ) + ")";
            case Opera:     untyped _style.OTransform       = "scaleY("+ Std.string( scaleY_ ) + ")";
            case Mozilla:   untyped _style.MozTransform     = "scaleY("+ Std.string( scaleY_ ) + ")";
            case IE:        affineTrans( scaleX, 0, 0, scaleY_, 0, 0 ) ;
        }
        
        _scaleY = scaleY_;
        return _scaleY;
        
    }
    
    

    public var scaleX( get_scaleX, set_scaleX ): Float;
    
    private function get_scaleX( ):Float
    {
        
        if( _scaleX == null ) _scaleX = 1;
        return _scaleX;
        
    }
    
    private function set_scaleX( scaleX_: Float ): Float
    {
        // a and d 
        switch( Browser.browserType )
        {
            case WebKit:    untyped _style.WebkitTransform  = "scaleX("+ Std.string( scaleX_ ) + ")";
            case Opera:     untyped _style.OTransform       = "scaleX("+ Std.string( scaleX_ ) + ")";
            case Mozilla:   untyped _style.MozTransform     = "scaleX("+ Std.string( scaleX_ ) + ")";
            case IE:        affineTrans( scaleX_, 0, 0, scaleY, 0, 0 ) ;
        }
        
        _scaleX = scaleX_;
        return _scaleX;
        
    }
    
    
    /*
        
        http://c2.com/cgi/wiki?AffineTransformation
        
        xnew = a*x + c*y + e
        ynew = b*x + d*y + f
    
    */
    public function affineTrans( a: Float, b: Float, c: Float, d: Float, e: Float, f: Float )
    {
        afflines = [a,b,c,d,e,f];
        var mat0 = 'matrix( '+ Std.string( a ) + ', ' + Std.string( b ) + ', ' + Std.string( c ) + ', ' + Std.string( d ) + ', ' ;
        var matrixFirefox = mat0 + Std.string( e ) + 'px, ' + Std.string( e ) + 'px ) ';
        var matrixGeneral = mat0 + Std.string( e ) + Std.string( e ) + ' ) ';
        switch( Browser.browserType )
        {
            
            case WebKit:    untyped _style.WebkitTransform  = matrixGeneral;
            case Opera:     untyped _style.OTransform       = matrixGeneral;
            case Mozilla:   untyped _style.MozTransform     = matrixFirefox ;
            case IE:        affineTransIE( a, b, c, d, e, f );
            
        }
        
        
    }
    
    
    // credit to http://extremelysatisfactorytotalitarianism.com/blog/?p=922 for code (  I am on a mac so untested! )
    private function affineTransIE( a: Float, b: Float, c: Float, d: Float, e: Float, f: Float )
    {
        
        // set linear transformation via Matrix Filter
        untyped _style.filter = 'progid:DXImageTransform.Microsoft.Matrix(M11=' + a + ', M21=' + b + ', M12=' + c + ', M22=' + d + ', SizingMethod="auto expand")';
        var w2 = width/2;//style.offsetWidth
        var h2 = height/2;//offsetHeight?
        x = Math.round( x + e - ( Math.abs(a) - 1)*w2 + Math.abs(c)*h2 ) ;
        y = Math.round( y + f - Math.abs(b)*w2 + (Math.abs(d) - 1)*h2 ) ;
        
    }
    
    
    public var rotation( get_rotation, set_rotation ): Float;
    /*
        xnew = a*x + c*y + e
        ynew = b*x + d*y + f
        xnew = cos(r)*x - sin(r)*y + e
        ynew = sin(r)*x + cos(r)*y + f
    */
    public function set_rotation( angle: Float ): Float
    {
        
        _rotation = angle;
        
        //if( _angle != Std.int( angle ) )
        //{
            _angle = Std.int( angle );
            var rad = _rotation*(Math.PI/180);
            var cos = Math.cos( rad );
            var sin = Math.sin( rad );
            
            switch( Browser.browserType )
            {
                case WebKit:    untyped _style.WebkitTransform  = "rotate("+ Std.string( _angle ) + "deg)";
                case Opera:     untyped _style.OTransform       = "rotate("+ Std.string( _angle ) + "deg)";
                case Mozilla:   untyped _style.MozTransform     = "rotate("+ Std.string( _angle ) + "deg)";
                case IE:        affineTrans( cos, -sin, sin, cos, 0, 0 );
                //case IE:        untyped _style.filter           = "progid:DXImageTransform.Microsoft.BasicImage(rotation=" + _angle + ")";
            }
            
        //}
        
        return angle;
        
    }
    
    
    public function get_rotation( ): Float
    {
        
        if( _rotation == null )
        {
            _rotation = 0;
            _angle = 0;
        }
        return _rotation;
        
    }
    
    
    public var alpha( get_alpha, set_alpha ): Float;
    
    public function get_alpha(): Float
    {
        
        if( _alpha == null ) _alpha = 1;
        return _alpha;
        
    }
    
    public function set_alpha( alpha_: Float ): Float
    {
        
        switch( Browser.browserType )
        {
            case Mozilla, Opera, WebKit: untyped _style.opacity  =  alpha_ ;
            case IE:                     untyped _style.filter   = 'alpha(opacity=' + Std.String( alpha_*10 ) + ')';
        }
        
        _alpha = alpha_;
        return _alpha;
        
    }
    
}